import redis


class LuckRedisHelperUtils:
    def __init__(self, host='localhost', port=6379, password=None, db=0):
        """
        初始化 Redis 连接
        :param host: Redis 服务器地址，默认为 localhost
        :param port: Redis 服务器端口，默认为 6379
        :param db: 要使用的 Redis 数据库编号，默认为 0
        :param password: Redis 服务器密码，默认为 None
        """
        try:
            self.redis_client = redis.Redis(
                host=host,
                port=port,
                db=db,
                password=password,
                decode_responses=True  # 自动解码响应结果
            )
            # 测试连接
            self.redis_client.ping()
            print("成功连接到 Redis 服务器")
        except redis.exceptions.ConnectionError as e:
            print(f"无法连接到 Redis 服务器: {e}")
        except redis.exceptions.AuthenticationError as e:
            print(f"Redis 认证失败: {e}")

    def set(self, key, value, ex=None, px=None, nx=False, xx=False):
        """
        设置 Redis 键值对
        :param key: 键
        :param value: 值
        :param ex: 过期时间（秒）
        :param px: 过期时间（毫秒）
        :param nx: 如果设置为 True，则只有当键不存在时才设置
        :param xx: 如果设置为 True，则只有当键已经存在时才设置
        :return: 设置成功返回 True，失败返回 False
        """
        return self.redis_client.set(key, value, ex=ex, px=px, nx=nx, xx=xx)

    def get(self, key):
        """
        获取 Redis 键对应的值
        :param key: 键
        :return: 键对应的值，如果键不存在则返回 None
        """
        return self.redis_client.get(key)

    def delete(self, *keys):
        """
        删除一个或多个 Redis 键
        :param keys: 要删除的键，可以传入多个键
        :return: 删除的键的数量
        """
        return self.redis_client.delete(*keys)

    def exists(self, key):
        """
        检查 Redis 键是否存在
        :param key: 键
        :return: 如果键存在返回 True，否则返回 False
        """
        return self.redis_client.exists(key)

    def expire(self, key, seconds):
        """
        为 Redis 键设置过期时间
        :param key: 键
        :param seconds: 过期时间（秒）
        :return: 如果设置成功返回 True，否则返回 False
        """
        return self.redis_client.expire(key, seconds)

    def get_ttl(self, key):
        """
        获取 Redis 键的剩余过期时间
        :param key: 键
        :return: 剩余过期时间（秒），如果键不存在或没有设置过期时间返回 -1
        """
        return self.redis_client.ttl(key)

    def hset(self, name, key, value):
        """
        在 Redis 哈希表中设置字段和值
        :param name: 哈希表的名称
        :param key: 字段名
        :param value: 字段值
        :return: 如果字段是新设置的返回 1，如果字段已经存在并被更新返回 0
        """
        return self.redis_client.hset(name, key, value)

    def hget(self, name, key):
        """
        从 Redis 哈希表中获取字段的值
        :param name: 哈希表的名称
        :param key: 字段名
        :return: 字段的值，如果字段不存在返回 None
        """
        return self.redis_client.hget(name, key)

    def hdel(self, name, *keys):
        """
        从 Redis 哈希表中删除一个或多个字段
        :param name: 哈希表的名称
        :param keys: 要删除的字段名，可以传入多个字段名
        :return: 删除的字段数量
        """
        return self.redis_client.hdel(name, *keys)

    def lpush(self, name, *values):
        """
        将一个或多个值插入到 Redis 列表的头部
        :param name: 列表的名称
        :param values: 要插入的值，可以传入多个值
        :return: 插入后列表的长度
        """
        return self.redis_client.lpush(name, *values)

    def rpush(self, name, *values):
        """
        将一个或多个值插入到 Redis 列表的尾部
        :param name: 列表的名称
        :param values: 要插入的值，可以传入多个值
        :return: 插入后列表的长度
        """
        return self.redis_client.rpush(name, *values)

    def lrange(self, name, start, end):
        """
        获取 Redis 列表中指定范围的元素
        :param name: 列表的名称
        :param start: 起始索引
        :param end: 结束索引
        :return: 包含指定范围元素的列表
        """
        return self.redis_client.lrange(name, start, end)

    def sadd(self, name, *values):
        """
        向 Redis 集合中添加一个或多个成员
        :param name: 集合的名称
        :param values: 要添加的成员，可以传入多个成员
        :return: 成功添加的成员数量
        """
        return self.redis_client.sadd(name, *values)

    def smembers(self, name):
        """
        获取 Redis 集合中的所有成员
        :param name: 集合的名称
        :return: 包含集合所有成员的集合
        """
        return self.redis_client.smembers(name)

    def srem(self, name, *values):
        """
        从 Redis 集合中移除一个或多个成员
        :param name: 集合的名称
        :param values: 要移除的成员，可以传入多个成员
        :return: 成功移除的成员数量
        """
        return self.redis_client.srem(name, *values)
